package cn.jjxx.modules.sys.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import cn.jjxx.core.common.service.impl.CommonServiceImpl;
import cn.jjxx.core.query.wrapper.EntityWrapper;
import cn.jjxx.core.utils.ObjectUtils;
import cn.jjxx.core.utils.StringUtils;
import cn.jjxx.modules.sys.mapper.BillRuleMapper;
import cn.jjxx.modules.sys.entity.BillRule;
import cn.jjxx.modules.sys.entity.BillRuleDetail;
import cn.jjxx.modules.sys.service.IBillRuleDetailService;
import cn.jjxx.modules.sys.service.IBillRuleService;
import cn.jjxx.modules.sys.utils.BillRuleUtil;
import cn.jjxx.modules.sys.utils.BillRuleUtil.RuleTypes;

import org.framework.customutil.StrCoverUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.annotations.TableName;

/**   
 * @Title: 单号规则
 * @Description: 单号规则
 * @author zcg
 * @date 2018-08-09 14:01:03
 * @version V1.0   
 *
 */
@Transactional
@Service("billRuleService")
public class BillRuleServiceImpl  extends CommonServiceImpl<BillRuleMapper,BillRule> implements  IBillRuleService {
	
	@Autowired
	protected IBillRuleDetailService billRuleDetailService;

	@Override
	public boolean insertBatch(List<BillRule> list) {
		if(list!=null&&list.size()>0){
			return baseMapper.insertBatch(list);
		}
		return true;
	}

	@Override
	public boolean updateBatch(List<BillRule> list) {
		if(list!=null&&list.size()>0){
			return baseMapper.updateBatch(list);
		}
		return true;
	}

	@Override
	public String createBillNum(String menuId, Object... params) {
		return createNum(menuId, null);
	}

	@Override
	public String createBillNum(String menuId, Class<?> cls, Object... params) {
		TableName table = cls.getAnnotation(TableName.class);
		String tableName = table.value();
		return createNum(menuId, tableName, params);
	}

	@Override
	public String createBillNum(String menuId, String tableName,
			Object... params) {
		return createNum(menuId, tableName, params);
	}
	
	/**
	 * @Description: 创建规则单号 .<br>
	 * @param menuId 菜单Id.<br>
	 * @param tableName 表名.<br>
	 * @param params sql参数.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午10:35:30.<br>
	 */
	private String createNum(String menuId, String tableName,Object... params){
		int startPos = 1;
		String billNum = null;
		BillRule rule = getBillRule(menuId);
		if(rule!=null){
			List<BillRuleDetail> details = getBillRuleDetailList(rule.getId());
			for(BillRuleDetail detail:details){
				if(StringUtils.isNotEmpty(billNum)){
					billNum = billNum + getCreateRuleNum(rule, detail, tableName,startPos, params);
					startPos = billNum.length();
				}else{
					billNum = getCreateRuleNum(rule, detail, tableName,startPos, params);
				}
			}
		}
		return billNum;
	}
	
	/**
	 * @Description: 获取规则生成的单号 .<br>
	 * @param billRule 规则.<br>
	 * @param detail 规则明细.<br>
	 * @param tableName 表名.<br>
	 * @param params sql参数.<br>
	 * @return 返回规则单号.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午10:53:26.<br>
	 */
	private String getCreateRuleNum(BillRule billRule,BillRuleDetail detail,
			String tableName,int startPos,Object...params){
		String str = null;
		int type = Integer.valueOf(detail.getRuleType());
		RuleTypes rule = BillRuleUtil.ruleType(type);
		if(BillRuleUtil.RuleTypes.GDZ.equals(rule)){
			str = getFixed(detail);
		}else if(BillRuleUtil.RuleTypes.XTSJ.equals(rule)){
			str = getDateFormat(detail);
		}else if(BillRuleUtil.RuleTypes.SXH.equals(rule)){
			str = getSortNum(billRule, detail, tableName,startPos);
		}else if(BillRuleUtil.RuleTypes.SJS.equals(rule)){
			str = getRandom(detail);
		}else if(BillRuleUtil.RuleTypes.ZDYSQL.equals(rule)){
			str = getCustomSql(detail, params);
		}
		return str;
	}
	
	/**
	 * @Description: 根据菜单Id获取规则 .<br>
	 * @param menuId 惨淡Id.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午10:03:16.<br>
	 */
	private BillRule getBillRule(String menuId){
		EntityWrapper<BillRule> wrapper = new EntityWrapper<BillRule>(BillRule.class);
		wrapper.eq("menu", menuId);
		return this.selectOne(wrapper);
	}
	
	/**
	 * @Description: 根据规则，获取规则明细 .<br>
	 * @param fid 规则Id.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午10:02:36.<br>
	 */
	private List<BillRuleDetail> getBillRuleDetailList(String fid){
		EntityWrapper<BillRuleDetail> wrapper = new EntityWrapper<BillRuleDetail>(BillRuleDetail.class);
		wrapper.eq("fid", fid);
		wrapper.orderBy("sort");
		return billRuleDetailService.selectList(wrapper);
	}
	
	/**
	 * @Description: 获取固定值属性 .<br>
	 * @param detail 规则明细.<br>
	 * @return 返回固定值规则值.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午9:37:53.<br>
	 */
	private String getFixed(BillRuleDetail detail){
		StringBuffer str = new StringBuffer();
		str.append(detail.getValue());
		String sf = detail.getIsSeparator();
		if(sf.equals(String.valueOf(1))){
			str.append(detail.getSeparator());
		}
		return str.toString();
	}
	
	/**
	 * @Description: 获取系统日期格式值 .<br>
	 * @param detail 规则明细.<br>
	 * @return 返回系统日期格式.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午9:39:32.<br>
	 */
	private String getDateFormat(BillRuleDetail detail){
		StringBuffer str = new StringBuffer();
		String sf = detail.getIsSeparator();
		String format = detail.getDateFormat();
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Date date = new Date();
		str.append(sdf.format(date));
		if(sf.equals(String.valueOf(1))){
			str.append(detail.getSeparator());
		}
		return str.toString();
	}
	
	/**
	 * @Description: 获取顺序号 .<br>
	 * @param rule 规则.<br>
	 * @param detail 规则明细.<br>
	 * @param tableName 表名.<br>
	 * @return 返回顺序号.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午9:42:52.<br>
	 */
	private String getSortNum(BillRule rule,BillRuleDetail detail,String tableName,int startPos){
		StringBuffer str = new StringBuffer();
		String sf = detail.getIsSeparator();
		String initValue = detail.getInitialValue();
		String step = detail.getStep();
		String coverValue = detail.getCoverValue();
		int length = Integer.valueOf(detail.getLength());
		String feild = rule.getNumFeild();
		String sortNum = getMaxSortNum(tableName, feild, startPos,length );
		if(StringUtils.isNotEmpty(sortNum)){
			int maxNum = Integer.valueOf(sortNum).intValue()+Integer.valueOf(step);
			String newSortNum = StrCoverUtil.cover(String.valueOf(maxNum), true, coverValue, length);
			str.append(newSortNum);
		}else{
			int maxNum = Integer.valueOf(initValue).intValue();
			String newSortNum = StrCoverUtil.cover(String.valueOf(maxNum), true, coverValue, length);
			str.append(newSortNum);
		}
		if(sf.equals(String.valueOf(1))){
			str.append(detail.getSeparator());
		}
		return str.toString();
	}
	
	/**
	 * @Description: 获取数据库最大单号 .<br>
	 * @param tableName 表名.<br>
	 * @param feild 字段名.<br>
	 * @param startPos 开始位置.<br>
	 * @param length 长度.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 下午11:03:54.<br>
	 */
	private String getMaxSortNum(String tableName,String feild,int startPos,int length){
		StringBuffer sql = new StringBuffer();
		sql.append(" select ");
		sql.append(" SUBSTR(").append(feild).append(",");
		sql.append(startPos+1).append(",").append(length).append(")");
		sql.append(" as sortNum");
		sql.append(" from ").append(tableName);
		sql.append(" order by ");
		sql.append(" SUBSTR(").append(feild).append(",");
		sql.append(startPos+1).append(",").append(length).append(") desc");
		sql.append(" limit 0,1 ");
		return baseMapper.selectBySql(sql.toString());
	}
	
	/**
	 * @Description: 获取随机数 .<br>
	 * @param detail 规则明细.<br>
	 * @return 返回随机数.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午9:44:37.<br>
	 */
	private String getRandom(BillRuleDetail detail){
		
		String random = "";
		/*随机数函数*/
		java.util.Random r=new java.util.Random();
		for(int i = 0;i<8;i++){
			/*生成36以内的随机数，不含36，并转化为36位*/
			random += Integer.toString(r.nextInt(36), 36);
		}
		return random;

	}
	
	/**
	 * @Description: 获取sql定义的唯一值 .<br>
	 * @param detail 规则明细 .<br>
	 * @param params 参数 .<br>
	 * @return 返回sql的唯一值.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-8-10 上午9:45:01.<br>
	 */
	private String getCustomSql(BillRuleDetail detail,Object...params){
		StringBuffer sql = new StringBuffer();
		return baseMapper.selectBySql(sql.toString());
	}

	@Override
	public String createBillNumber(String billRuleNumber, Object... params) {
		EntityWrapper<BillRule> wrapper = new EntityWrapper<BillRule>(BillRule.class);
		wrapper.eq("number", billRuleNumber);
		BillRule rule = this.selectOne(wrapper);
		if(!ObjectUtils.isNullOrEmpty(rule)){
			return createBillNum(rule.getMenu());
		}
		return null;
	}

	@Override
	public String createBillNumber(String billRuleNumber, Class<?> cls, Object... params) {
		EntityWrapper<BillRule> wrapper = new EntityWrapper<BillRule>(BillRule.class);
		wrapper.eq("number", billRuleNumber);
		BillRule rule = this.selectOne(wrapper);
		if(!ObjectUtils.isNullOrEmpty(rule)){
			return createBillNum(rule.getMenu(),cls);
		}
		return null;
	}

	@Override
	public String createBillNumber(String billRuleNumber, String tableName, Object... params) {
		EntityWrapper<BillRule> wrapper = new EntityWrapper<BillRule>(BillRule.class);
		wrapper.eq("number", billRuleNumber);
		BillRule rule = this.selectOne(wrapper);
		if(!ObjectUtils.isNullOrEmpty(rule)){
			return createBillNum(rule.getMenu(),tableName);
		}
		return null;
	}
	
}
